﻿#include "fcgiplus.hpp"
#include "eiendb.hpp"
#include "eiennet.hpp"
#include "eiengd.hpp"
#include "eienexpr.hpp"
#include "eientpl.hpp"
#include "fcgiserv.hpp"
#include <iostream>
using namespace std;
using namespace winux;
using namespace eiendb;
using namespace eiennet;
using namespace eiengd;
using namespace eienexpr;
using namespace eientpl;
using namespace fcgi;

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <termios.h>

// 清除屏幕
#define CLEAR() printf("\033[2J")
// 上移光标
#define MOVEUP(x) printf("\033[%dA", (x))
// 下移光标
#define MOVEDOWN(x) printf("\033[%dB", (x))
// 左移光标
#define MOVELEFT(y) printf("\033[%dD", (y))
// 右移光标
#define MOVERIGHT(y) printf("\033[%dC",(y))
// 定位光标
#define MOVETO(x,y) printf("\033[%d;%dH", (x), (y))
// 光标复位
#define RESET_CURSOR() printf("\033[H")
// 隐藏光标
#define HIDE_CURSOR() printf("\033[?25l")
// 显示光标
#define SHOW_CURSOR() printf("\033[?25h")
//反显
#define HIGHT_LIGHT() printf("\033[7m")
#define UN_HIGHT_LIGHT() printf("\033[27m")

#define RESTORE() printf("\33[0m")


class TerminalDisplay {
public:
    TerminalDisplay() :
        __cursorCol(0),
        __cursorRow(0),
        __startTime( GetUtcTimeMs() )
    {
        getSize();
        moveTo(__cursorCol,__cursorRow);
    }
    void getSize(){
        //TIOCSWINSZ命令可以将此结构的新值存放到内核中
        ioctl(STDIN_FILENO,TIOCGWINSZ,&__winsize);
    }
    
    inline int width() const {
        return __winsize.ws_col;
    }
    inline int height() const {
        return __winsize.ws_row;
    }
    void moveTo( int col, int row ) {
        __cursorCol = col;
        __cursorRow = row;
        MOVETO(col,row);
    }
    void clear(){
        // CLEAR();
        // RESET_CURSOR();
        int w = width();
        int h = height();

        printf("\33[30m\33[40m");
        String clearStr = " ";
        for(int r=1;r<=h;r++) {
            for(int c=1;c<=w;c++) {
                out( c, r, clearStr );
            }
        }
        RESTORE();
    }
    void out( int col, int row, String const& str ) {
        String pos = Format( "\033[%d;%dH", row, col );
        String in = (pos+str);

	    write(1,in.c_str(),in.size());
    }

    float getTimeDelta(){
        int nowTime = GetUtcTimeMs();
        int delta = nowTime - __startTime;
        __startTime = nowTime;
        return delta;
    }

private:
    struct winsize __winsize;
    int __cursorCol;
    int __cursorRow;

    int __startTime;
};


class FastdoDebuger {
    String _fileName;
    Mixed _m;
    Mixed _stack;
public:
    FastdoDebuger( String const& name ) {
        _fileName = name;
        _m.createCollection();
        _m["stack"].createArray();
    }
    ~FastdoDebuger() {
        String path = "debug/" + _fileName;
        FilePutContents( path, _m.myJson() );
    }
    
    FastdoDebuger& operator<< ( Mixed const & msg )
    {
        _m["stack"].add( msg );
        return *this;
    }
    template<typename _ChTy >
    Mixed const& operator[] ( _ChTy const * k ) const
    {
        return this->_m[k];
    }
    template<typename _ChTy >
    Mixed & operator [] ( _ChTy const * k )
    {
        return this->_m[k];
    }
    Mixed & operator [] ( Mixed const & k )
    {
        return this->_m[k];
    }
};

int main( int argc, char const * argv[] )
{
#if defined(__GNUC__) && !defined(WIN32) // on linux
    SetLocale::Set("zh_CN.UTF-8");
#endif
    winux::SetLocale __loc__;
    try
    {
// `display/display.inc.ecp` embed code is empty!
// `../include/debuger.ecp` embed code is empty!



TerminalDisplay display;
{
    FastdoDebuger debug("outputCard");
    debug["width"] = display.width();
    debug["height"] = display.height();
}


Template tpl( "" );
Mixed & card = tpl.getVarContext()->set("card");
card.createCollection();
card["name"] = "A";
card["type"] = "2";
String cardStr = tpl.output("card");


float intervalTime = 0.5f;
float curIntervalTime = 0.0f;
while(1){
    curIntervalTime += ((float)display.getTimeDelta()) / 1000.0;
    if( curIntervalTime < intervalTime ){
        continue;
    }

    curIntervalTime = 0.0f;

    display.clear();

    // MOVETO(0,0);
    display.out( 1,1, cardStr );
    display.out( 10,1, cardStr );
}

    }
    catch ( std::exception const & e )
    {
        cout << e.what() << endl;
    }
    catch (...)
    {
        cout << "Unknown error" << endl;
    }
    return 0;
}

